#include "wxslistbook.h"
#include "../../wxsadvqppchild.h"
#include "../wxsitemresdata.h"
#include <wx/listbook.h>
#include <wx/sizer.h>
#include <wx/textctrl.h>
#include <wx/checkbox.h>
#include <wx/panel.h>
#include <wx/intl.h>
#include <wx/string.h>

namespace {
  wxsRegisterItem<wxsListbook> Reg( _T( "Listbook" ), _T( "列表簿" ), wxsTContainer, _T( "标准" ), 250 );
  class wxsListbookExtra: public wxsPropertyContainer {
    public:
      wxsListbookExtra():
        m_Label( _T( "Page name" ) ),
        m_Selected( false ) {}
      wxString m_Label;
      bool m_Selected;
    protected:
      virtual void OnEnumProperties( M_Code_unused long Flags ) {
        WXS_SHORT_STRING( wxsListbookExtra, m_Label, _T( "Page name" ), _T( "label" ), _T( "" ), false );
        WXS_BOOL( wxsListbookExtra, m_Selected, _T( "Page selected" ), _T( "selected" ), false );
      }
  };

  class wxsListbookParentQP: public wxsAdvQPPChild {
    public:
      wxsListbookParentQP( wxsAdvQPP* parent, wxsListbookExtra* Extra, wxWindowID id = -1 ):
        wxsAdvQPPChild( parent, _T( "Listbook" ) ),
        m_Extra( Extra ) {
        wxStaticBoxSizer* StaticBoxSizer2;
        wxStaticBoxSizer* StaticBoxSizer1;
        wxFlexGridSizer* FlexGridSizer1;
        Create( parent, id, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T( "id" ) );
        FlexGridSizer1 = new wxFlexGridSizer( 0, 1, 0, 0 );
        StaticBoxSizer1 = new wxStaticBoxSizer( wxVERTICAL, this, _T( "Label" ) );
        Label = new wxTextCtrl( this, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T( "ID_TEXTCTRL1" ) );
        StaticBoxSizer1->Add( Label, 0, wxEXPAND, 5 );
        FlexGridSizer1->Add( StaticBoxSizer1, 1, wxEXPAND, 5 );
        StaticBoxSizer2 = new wxStaticBoxSizer( wxHORIZONTAL, this, _T( "Selection" ) );
        Selected = new wxCheckBox( this, ID_CHECKBOX1, _T( "Selected" ), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T( "ID_CHECKBOX1" ) );
        Selected->SetValue( false );
        StaticBoxSizer2->Add( Selected, 1, wxEXPAND, 5 );
        FlexGridSizer1->Add( StaticBoxSizer2, 1, wxEXPAND, 5 );
        SetSizer( FlexGridSizer1 );
        FlexGridSizer1->Fit( this );
        FlexGridSizer1->SetSizeHints( this );
        Connect( ID_TEXTCTRL1, wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( wxsListbookParentQP::OnLabelText ) );
        Connect( ID_CHECKBOX1, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( wxsListbookParentQP::OnSelectionChange ) );
        ReadData();
        Label->Connect( -1, wxEVT_KILL_FOCUS, ( wxObjectEventFunction )&wxsListbookParentQP::OnLabelKillFocus, 0, this );
      }

      virtual ~wxsListbookParentQP() {
      }

    private:
      virtual void Update() {
        ReadData();
      }

      void ReadData() {
        if( !GetPropertyContainer() || !m_Extra ) {
          return;
        }
        Label->SetValue( m_Extra->m_Label );
        Selected->SetValue( m_Extra->m_Selected );
      }

      void SaveData() {
        if( !GetPropertyContainer() || !m_Extra ) {
          return;
        }
        m_Extra->m_Label = Label->GetValue();
        m_Extra->m_Selected = Selected->GetValue();
        NotifyChange();
      }
      static const long ID_TEXTCTRL1;
      static const long ID_CHECKBOX1;
      void OnLabelText( wxCommandEvent& event );
      void OnLabelKillFocus( wxFocusEvent& event );
      void OnSelectionChange( wxCommandEvent& event );
      wxCheckBox* Selected;
      wxTextCtrl* Label;
      wxsListbookExtra* m_Extra;
      DECLARE_EVENT_TABLE()
  };


  const long wxsListbookParentQP::ID_TEXTCTRL1 = wxNewId();
  const long wxsListbookParentQP::ID_CHECKBOX1 = wxNewId();
  BEGIN_EVENT_TABLE( wxsListbookParentQP, wxPanel )
  END_EVENT_TABLE()
  void wxsListbookParentQP::OnLabelText( M_Code_unused wxCommandEvent& event )       { SaveData(); }
  void wxsListbookParentQP::OnLabelKillFocus( wxFocusEvent& event )              { SaveData(); event.Skip(); }
  void wxsListbookParentQP::OnSelectionChange( M_Code_unused wxCommandEvent& event ) { SaveData(); }
  WXS_ST_BEGIN( wxsListbookStyles, _T( "" ) )
  WXS_ST_CATEGORY( "wxListbook" )
  WXS_ST( wxLB_DEFAULT )
  WXS_ST( wxLB_LEFT )
  WXS_ST( wxLB_RIGHT )
  WXS_ST( wxLB_TOP )
  WXS_ST( wxLB_BOTTOM )
  WXS_ST_DEFAULTS()
  WXS_ST_END()
  WXS_EV_BEGIN( wxsListbookEvents )
  WXS_EVI( EVT_LISTBOOK_PAGE_CHANGED, wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED, wxListbookEvent, PageChanged )
  WXS_EVI( EVT_LISTBOOK_PAGE_CHANGING, wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING, wxListbookEvent, PageChanging )
  WXS_EV_END()

}

wxsListbook::wxsListbook( wxsItemResData* Data ):
  wxsContainer(
    Data,
    &Reg.Info,
    wxsListbookEvents,
    wxsListbookStyles ),
  m_CurrentSelection( 0 ) {
}

void wxsListbook::OnEnumContainerProperties( M_Code_unused long Flags ) {
}

bool wxsListbook::OnCanAddChild( wxsItem* Item, bool ShowMessage ) {
  if( Item->GetType() == wxsTSizer ) {
    if( ShowMessage ) {
      wxMessageBox( _T( "Can not add sizer into Listbook.\nAdd panels first" ) );
    }
    return false;
  }
  return wxsContainer::OnCanAddChild( Item, ShowMessage );
}

wxsPropertyContainer* wxsListbook::OnBuildExtra() {
  return new wxsListbookExtra();
}

wxString wxsListbook::OnXmlGetExtraObjectClass() {
  return _T( "listbookpage" );
}

void wxsListbook::OnAddChildQPP( wxsItem* Child, wxsAdvQPP* QPP ) {
  wxsListbookExtra* LBExtra = ( wxsListbookExtra* )GetChildExtra( GetChildIndex( Child ) );
  if( LBExtra ) {
    QPP->Register( new wxsListbookParentQP( QPP, LBExtra ), _T( "Listbook" ) );
  }
}

wxObject* wxsListbook::OnBuildPreview( wxWindow* Parent, long PreviewFlags ) {
  UpdateCurrentSelection();
  wxListbook* Listbook = new wxListbook( Parent, -1, Pos( Parent ), Size( Parent ), Style() );
  if( !GetChildCount() && !( PreviewFlags & pfExact ) ) {
    Listbook->AddPage(
      new wxPanel( Listbook, -1, wxDefaultPosition, wxSize( 50, 50 ) ),
      _T( "No pages" ) );
  }
  AddChildrenPreview( Listbook, PreviewFlags );
  for( int i = 0; i < GetChildCount(); i++ ) {
    wxsItem* Child = GetChild( i );
    wxsListbookExtra* LBExtra = ( wxsListbookExtra* )GetChildExtra( i );
    wxWindow* ChildPreview = wxDynamicCast( GetChild( i )->GetLastPreview(), wxWindow );
    if( !ChildPreview ) {
      continue;
    }
    bool Selected = ( Child == m_CurrentSelection );
    if( PreviewFlags & pfExact ) {
      Selected = LBExtra->m_Selected;
    }
    Listbook->AddPage( ChildPreview, LBExtra->m_Label, Selected );
  }
  return Listbook;
}

void wxsListbook::OnBuildCreatingCode() {
  switch( GetLanguage() ) {
  case wxsCPP: {
    AddHeader( _T( "<wx/listbook.h>" ), GetInfo().ClassName, 0 );
    AddHeader( _T( "<wx/notebook.h>" ), _T( "wxNotebookEvent" ), 0 );
    Codef( _T( "%C(%W, %I, %P, %S, %T, %N);\n" ) );
    BuildSetupWindowCode();
    AddChildrenCode();
    for( int i = 0; i < GetChildCount(); i++ ) {
      wxsListbookExtra* LBExtra = ( wxsListbookExtra* )GetChildExtra( i );
      Codef( _T( "%AAddPage(%o, %t, %b);\n" ), i, LBExtra->m_Label.wx_str(), LBExtra->m_Selected );
    }
    break;
  }
  case wxsUnknownLanguage:
  default: {
    wxsCodeMarks::Unknown( _T( "wxsListbook::OnBuildCreatingCode" ), GetLanguage() );
  }
  }
}

bool wxsListbook::OnMouseClick( wxWindow* Preview, int PosX, int PosY ) {
  UpdateCurrentSelection();
  wxListbook* Listbook = ( wxListbook* )Preview;
  int Hit = ( ( wxBookCtrlBase* )Listbook )->HitTest( wxPoint( PosX, PosY ) );
  if( Hit != wxNOT_FOUND ) {
    wxsItem* OldSel = m_CurrentSelection;
    m_CurrentSelection = GetChild( Hit );
    GetResourceData()->SelectItem( m_CurrentSelection, true );
    return OldSel != m_CurrentSelection;
  }
  return false;
}

bool wxsListbook::OnIsChildPreviewVisible( wxsItem* Child ) {
  UpdateCurrentSelection();
  return Child == m_CurrentSelection;
}

bool wxsListbook::OnEnsureChildPreviewVisible( wxsItem* Child ) {
  if( IsChildPreviewVisible( Child ) ) {
    return false;
  }
  m_CurrentSelection = Child;
  UpdateCurrentSelection();
  return true;
}

void wxsListbook::UpdateCurrentSelection() {
  wxsItem* NewCurrentSelection = 0;
  for( int i = 0; i < GetChildCount(); i++ ) {
    if( m_CurrentSelection == GetChild( i ) ) {
      return;
    }
    wxsListbookExtra* LBExtra = ( wxsListbookExtra* )GetChildExtra( i );
    if( ( i == 0 ) || LBExtra->m_Selected ) {
      NewCurrentSelection = GetChild( i );
    }
  }
  m_CurrentSelection = NewCurrentSelection;
}
